package com.polaris.live.ui.live.proxy

import com.polaris.live.common.AppModule
import com.polaris.live.common.manager.CoroutineScopeManager
import com.polaris.live.common.util.JsonUtils
import com.polaris.live.common.util.LogExt
import com.polaris.live.constant.LiveConst
import com.polaris.live.manager.LanguageManage
import com.polaris.live.resp.back_resp.RecognizeModel
import com.polaris.live.ui.live.widget.listener.OnCallTranslationListener
import com.polaris.live.utils.CommonUtils
import com.polaris.live.utils.zego.LiveEngineManage
import im.zego.realtimetranslation.IZegoRealtimeTranslationHandler
import im.zego.realtimetranslation.ZegoRTServiceProvider
import im.zego.zegoexpress.callback.IZegoAudioDataHandler
import im.zego.zegoexpress.constants.ZegoAudioChannel
import im.zego.zegoexpress.constants.ZegoAudioDataCallbackBitMask
import im.zego.zegoexpress.constants.ZegoAudioSampleRate
import im.zego.zegoexpress.entity.ZegoAudioFrameParam
import kotlinx.coroutines.launch
import java.nio.ByteBuffer
import java.nio.charset.StandardCharsets

/**
 * 同声传译代理类
 * @author Created by 半仙 on 2023/11/29/029 17:04
 */
class LiveTranslationProxy(
    private val onCallTranslationListener: OnCallTranslationListener,
) {
    /**
     * TODO 后续优化点  如果是直播坐等没有必要每次都反初始化  可以考虑直接换语言即可  目前时间有点紧所以后续再优化
     */
    //是否初始化过   0的时候就代表初始化过了
    private var translationInit = -1

    //注意类名
    //初始化
    fun initKey(key: String, translationLanguage: String, speechLanguage: String) {
        if (!AppModule.checkGoogleServices()) {
            return
        }
        initTranslation(key, translationLanguage, speechLanguage)
    }

    /**
     * 停止同声传译
     */
    fun stopTranslation(needUnInit: Boolean = false) {
        if (translationInit != 0) return
        LogExt.logI("--live") {
            "============ 传译 ！停止！ ==========="
        }
        LiveEngineManage.getTranslationEngine().stopRealtimeTranslation()
        LogExt.logI("--live") {
            "============ $needUnInit ==========="
        }
        if (needUnInit) {
            LogExt.logI("--live") {
                "============ 传译 ！反初始化！ ==========="
            }
            LiveEngineManage.getTranslationEngine().unInit()
            translationInit = -1
        }
    }

    /**
     * 开启同声传译
     */
    fun startTranslation() {
        if (translationInit != 0 || isStartTranslation()) return
        val startRealtimeTranslation =
            LiveEngineManage.getTranslationEngine().startRealtimeTranslation()
        LogExt.logI("--live") {
            "============ 传译 ！出击！ ===========: Code = $startRealtimeTranslation"
        }
    }

    /**
     * 设置对方的语言
     */
    fun setTranslationLanguage(language: String) {
        if (translationInit != 0) return
        stopTranslation()
        LogExt.logI("--live") {
            "============ 给对方上语言 ===========:传来的：$language == 既构的 = " +
                    "${LanguageManage.getTranslationLanguage(language)}"
        }
        LiveEngineManage.getTranslationEngine().targetTranslationLanguage =
            LanguageManage.getTranslationLanguage(language) // 设置翻译的目标语言
        startTranslation()
    }

    /**
     * 设置自己的语言
     */
    fun setSpeechLanguage(language: String) {
        if (translationInit != 0) return

        stopTranslation()
        LogExt.logI("--live") {
            "============ 设置自己的家乡话 ===========: Code = " +
                    "${LanguageManage.getTranslationSpeech(language)}"
        }
        LiveEngineManage.getTranslationEngine().sourceSpeechLanguage =
            LanguageManage.getTranslationSpeech(language) // 设置语音识别的语言
        startTranslation()
    }

    /**
     * 初始化同声传译sdk
     */
    private fun initTranslation(key: String, translationLanguage: String, speechLanguage: String) {

        if (translationInit == 0) return

        translationInit = LiveEngineManage.getTranslationEngine().init(key) // 传入申请到的license

        LogExt.logI("--live") {
            "============ 俺同声传译初始化了 ===========: Code = $translationInit"
        }

        LogExt.logI("--live") {
            "============ translationLanguage ===========: Code = $translationLanguage"
        }

        // 设置采集声音的参数，必须sampleRate是16k，单声道格式。
        val audioFrameParam = ZegoAudioFrameParam()
        audioFrameParam.sampleRate = ZegoAudioSampleRate.ZEGO_AUDIO_SAMPLE_RATE_16K
        audioFrameParam.channel = ZegoAudioChannel.MONO

        LiveEngineManage.getEngine()?.startAudioDataObserver(
            ZegoAudioDataCallbackBitMask.CAPTURED.value(),
            audioFrameParam
        )
        // 设置接收麦克风收集到的声音数据回调，并传给ZegoRealtimeTranslation SDK.
        LiveEngineManage.getEngine()?.setAudioDataHandler(object : IZegoAudioDataHandler() {
            override fun onCapturedAudioData(
                data: ByteBuffer,
                dataLength: Int,
                param: ZegoAudioFrameParam?,
            ) {
                LiveEngineManage.getTranslationEngine().sendSpeechPCM(
                    CommonUtils.byteBufferToByteArray(data),
                    dataLength
                )
            }
        })

        LiveEngineManage.getTranslationEngine().enableTranslate(true) // 如果不需要翻译可以设置为false
        LiveEngineManage.getTranslationEngine()
            .enableInterimTranslation(true)// 如果不需要中间结果翻译可以设置为false，开启会增加很多翻译请求量
        LiveEngineManage.getTranslationEngine().speechToTextService =
            ZegoRTServiceProvider.Google // 设置语音识别使用的服务提供商
        LiveEngineManage.getTranslationEngine().textTranslationService =
            ZegoRTServiceProvider.Google // 设置翻译使用的服务提供商

        LiveEngineManage.getTranslationEngine().sourceSpeechLanguage =
            LanguageManage.getTranslationSpeech(speechLanguage) // 设置语音识别的语言
        LiveEngineManage.getTranslationEngine().targetTranslationLanguage =
            LanguageManage.getTranslationLanguage(translationLanguage) // 设置翻译的目标语言

        LiveEngineManage.getTranslationEngine().setRealtimeTranslationHandler(object :
            IZegoRealtimeTranslationHandler {
            override fun onRecognizingText(text: String?) {
                if (!text.isNullOrEmpty()) {
                    val recognizeModel = RecognizeModel(content = text)
                    CoroutineScopeManager.mainScope.launch {
                        onCallTranslationListener.onTranslating(recognizeModel)
                    }
                }
                LogExt.logI("--live") {
                    "onRecognizingText: 未结束原文  $text"
                }
            }

            override fun onRecognizingTranslatedText(text: String?) {
                if (!text.isNullOrEmpty()) {
                    val recognizeModel = RecognizeModel(translationContent = text)
                    val str = (LiveConst.ZEGOTI + JsonUtils.toJson(recognizeModel))
                    LiveEngineManage.getEngine()?.sendSEI(str.toByteArray(StandardCharsets.UTF_8))
                }
                LogExt.logI("--live") {
                    "onRecognizingTranslatedText: 未结束译文  $text"
                }
            }

            override fun onRecognizedText(text: String?) {
                if (!text.isNullOrEmpty()) {
                    val recognizeModel = RecognizeModel(content = text, contentType = true)
                    CoroutineScopeManager.mainScope.launch {
                        onCallTranslationListener.onTranslated(recognizeModel)
                    }
                }
                LogExt.logI("--live") {
                    "onRecognizedText: 结束原文  $text"
                }
            }

            override fun onRecognizedTranslatedText(text: String?) {
                if (!text.isNullOrEmpty()) {
                    val recognizeModel =
                        RecognizeModel(translationContent = text, translationContentType = true)
                    val str = (LiveConst.ZEGOTD + JsonUtils.toJson(recognizeModel))
                    LiveEngineManage.getEngine()?.sendSEI(str.toByteArray(StandardCharsets.UTF_8))
                }
                LogExt.logI("--live") {
                    "本句话翻译结束     onRecognizedTranslatedText: 结束译文 $text"
                }
            }

            override fun onError(p0: Int) {
                LogExt.logI("--live") {
                    "onError: $p0"
                }
            }
        })
        val startRealtimeTranslation =
            LiveEngineManage.getTranslationEngine().startRealtimeTranslation()
        LogExt.logI("--live") {
            "============ 传译 ！出击！ ===========: Code = $startRealtimeTranslation"
        }
    }

    //是否开启了同声传译
    fun isStartTranslation() = LiveEngineManage.getTranslationEngine().isStartRealtimeTranslation

}